/*
 * @features: 功能
 * @description: 说明
 * @Date: 2021-09-13 23:49:48
 * @Author: judu233(769471424@qq.com)
 * @LastEditTime: 2021-10-06 13:29:34
 * @LastEditors: judu233
 */

import c3d from "../../cc";
import { Mathf } from "../../other/Mathf";
import ExtendsLoad from "../CCExtends";

declare module "cc" {
    export interface Vec3 {
        /**
          * 随时间变化进度值
          * @param start  起始位置
          * @param end    结束位置
          * @param t      [0，1]
          * @returns 
        */
        progress(start: c3d.Vec3, end: c3d.Vec3, t: number): void;
        /**
        * 球面插值
        * @param from 
        * @param to 
        * @param t 
        * @returns 
        */
        slerp(from: c3d.Vec3, to: c3d.Vec3, t: number): void;

        /**
         * 旋转
         * @param from 
         * @param to 
         * @param angle 
         */
        rotateTo(from: c3d.Vec3, to: c3d.Vec3, angle: number): void;
    }
}

class Vect3Extends {
    static progress(start: c3d.Vec3, end: c3d.Vec3, t: number) {
        var current = new c3d.Vec3();
        current.x = Mathf.progress(start.x, end.x, t);
        current.y = Mathf.progress(start.y, end.y, t);
        current.z = Mathf.progress(start.z, end.z, t);
        return current;
    }

    static slerp(from: c3d.Vec3, to: c3d.Vec3, t: number): c3d.Vec3 {
        if (t <= 0) {
            return from;
        }
        else if (t >= 1) {
            return to;
        }

        var dir: c3d.Vec3 = this.rotateTo(from, to, (c3d.Vec3.angle(from, to) / Math.PI * 180) * t);
        var lenght: number = to.length() * t + from.length() * (1 - t);

        return (dir.normalize()).multiplyScalar(lenght);
    }

    static rotateTo(from: c3d.Vec3, to: c3d.Vec3, angle: number): c3d.Vec3 {
        //如果两个方向角度为0，则返回目标
        if (c3d.Vec3.angle(from, to) == 0) {
            return to;
        }

        var axis: c3d.Vec3 = new c3d.Vec3()                 // 获得旋转轴
        c3d.Vec3.cross(axis, from, to);
        axis.normalize();

        var radian: number = angle * Math.PI / 180; // 获得弧度
        var rotateMatrix: c3d.Mat4 = new c3d.Mat4();
        rotateMatrix.rotate(radian, axis);

        return new c3d.Vec3(
            from.x * rotateMatrix.m00 + from.y * rotateMatrix.m04 + from.z * rotateMatrix.m08,
            from.x * rotateMatrix.m01 + from.y * rotateMatrix.m05 + from.z * rotateMatrix.m09,
            from.x * rotateMatrix.m02 + from.y * rotateMatrix.m06 + from.z * rotateMatrix.m10
        );
    }


}

ExtendsLoad.load(c3d.Vec3.prototype, Vect3Extends);